# 第一题：面向对象编程能力考核
# 实现一个简单的图形类层次结构，包括接口、继承、构造函数等概念

from abc import ABC, abstractmethod
import math

# 定义图形接口
"""
## 接口的特点
1. 只定义方法签名 ：接口只定义方法的名称、参数和返回类型，不包含方法的具体实现
2. 强制实现 ：任何实现接口的类必须提供接口中所有方法的具体实现
3. 实现多态 ：允许不同类的对象以相同方式处理，只要它们实现了相同的接口
## 您代码中的接口实现
在您的代码中， `Shape` 类就是一个接口的实现：
"""
class Shape(ABC):
    """抽象基类，定义图形接口"""
    
    def __init__(self, color):  
        """构造函数，初始化颜色"""
        self.color = color
    
    @abstractmethod#抽象类必须重写
    def area(self):
        """计算面积的抽象方法"""
        pass
    
    @abstractmethod
    def perimeter(self):
        """计算周长的抽象方法"""
        pass
    
    def describe(self):#具体方法，可以直接使用或重写
        """描述图形"""
        return f"这是一个{self.color}色的图形"

# 定义圆形类
class Circle(Shape):
    """圆形类，继承自Shape"""
    
    def __init__(self, color, radius):
        """构造函数，调用父类构造函数并初始化半径"""
        super().__init__(color)#color 属性 ：通过 super().__init__(color) 调用父类构造函数，Circle 对象获得了 color 属性
        self.radius = radius
    """
    Circle 类继承了 Shape 类的 所有方法 ，包括：

    1. 抽象方法 （必须重写）：
    - `area` - 计算面积的方法
    - `perimeter` - 计算周长的方法
    2. 具体方法 （可以直接使用或重写）：
    - `describe` - 描述图形的方法
    """
    def area(self):
        """计算圆的面积"""
        return math.pi * self.radius ** 2
    
    def perimeter(self):
        """计算圆的周长"""
        return 2 * math.pi * self.radius
    
    def describe(self):
        """描述圆形"""
        return f"这是一个{self.color}色的圆形，半径为{self.radius}"

# 定义矩形类
class Rectangle(Shape):
    """矩形类，继承自Shape"""
    
    def __init__(self, color, width, height):
        """构造函数，调用父类构造函数并初始化宽和高"""
        super().__init__(color)
        self.width = width
        self.height = height
    
    def area(self):
        """计算矩形的面积"""
        return self.width * self.height
    
    def perimeter(self):
        """计算矩形的周长"""
        return 2 * (self.width + self.height)
    
    def describe(self):
        """描述矩形"""
        return f"这是一个{self.color}色的矩形，宽为{self.width}，高为{self.height}"

# 定义正方形类，继承自矩形
class Square(Rectangle):
    """正方形类，继承自Rectangle"""
    
    def __init__(self, color, side):
        """构造函数，调用父类构造函数并初始化边长"""
        super().__init__(color, side, side)
        self.side = side
    
    def describe(self):
        """描述正方形"""
        return f"这是一个{self.color}色的正方形，边长为{self.side}"

# 定义图形管理类
class ShapeManager:
    """图形管理类，用于管理多个图形对象"""
    
    def __init__(self):
        """构造函数，初始化图形列表"""
        self.shapes = []
    
    def add_shape(self, shape):
        """添加图形到管理器"""
        if isinstance(shape, Shape):
            self.shapes.append(shape)
        else:
            raise TypeError("只能添加Shape对象或其子类对象")
    
    def total_area(self):
        """计算所有图形的总面积"""
        return sum(shape.area() for shape in self.shapes)
    
    def list_shapes(self):
        """列出所有图形的描述"""
        return [shape.describe() for shape in self.shapes]

# 测试代码
if __name__ == "__main__":
    # 创建不同图形对象
    circle = Circle("红", 5)
    rectangle = Rectangle("蓝", 4, 6)
    square = Square("绿", 3)
    
    # 创建图形管理器
    manager = ShapeManager()
    
    # 添加图形到管理器
    manager.add_shape(circle)
    manager.add_shape(rectangle)
    manager.add_shape(square)
    
    # 打印图形信息
    print("图形列表:")
    for desc in manager.list_shapes():
        print(desc)
    
    print("\n各图形面积和周长:")
    print(f"圆形面积: {circle.area():.2f}, 周长: {circle.perimeter():.2f}")
    print(f"矩形面积: {rectangle.area():.2f}, 周长: {rectangle.perimeter():.2f}")
    print(f"正方形面积: {square.area():.2f}, 周长: {square.perimeter():.2f}")
    
    print(f"\n所有图形总面积: {manager.total_area():.2f}")



#期末题
    #5、请设计一个Python多态（polymorphism）案例并通过主程序调用展示多态特性。
class Animal(object):
    """- object 是Python中所有类的最终父类
        - 它定义了所有Python对象共有的基本方法
        - 在Python 3中，即使不显式继承 object ，类也会自动继承它
    """
    def __init__(self, name):
        self.name = name
    def eat(self):
        print(self.name + ' is eating.')

class Dog(Animal):
    def __init__(self, name):
        super().__init__(name)# super().__init__() 只负责处理​​属性继承​​
        #Animal.__init__(self, name)
    def eat(self):
        print(self.name + ' is eating meat.')

class Cat(Animal):
    def __init__(self, name):
        Animal.__init__(self, name)
    def eat(self):
        print(self.name + ' is eating fish.')

def eat_all(animals):
    for animal in animals:
        animal.eat()

if __name__ == '__main__':
    animals = [Dog('Dog1'), Dog('Dog2'), Cat('Cat1'), Cat('Cat2')]
    eat_all(animals)